/*
 * $Id: GarbageFreeFormatterFactory.java 101 2013-01-14 12:51:21Z vladimirow@mail.ru $
 * $HeadURL: http://ultralog.googlecode.com/svn/ultralog/tags/release-20130123/src/java/com/google/code/ultralog/formatter/gfree/GarbageFreeFormatterFactory.java $
 *
 * This file is a part of ultralog project (http://code.google.com/p/ultralog/).
 * Released under New BSD License.
 */
package com.google.code.ultralog.formatter.gfree;

import java.util.TimeZone;

import com.google.code.ultralog.formatter.BooleanFormatter;
import com.google.code.ultralog.formatter.ByteFormatter;
import com.google.code.ultralog.formatter.CharacterFormatter;
import com.google.code.ultralog.formatter.DoubleFormatter;
import com.google.code.ultralog.formatter.FloatFormatter;
import com.google.code.ultralog.formatter.FormatterFactory;
import com.google.code.ultralog.formatter.IntegerFormatter;
import com.google.code.ultralog.formatter.LongFormatter;
import com.google.code.ultralog.formatter.ReferenceFormatter;
import com.google.code.ultralog.formatter.ShortFormatter;
import com.google.code.ultralog.formatter.def.DefaultReferenceFormatter;
import com.google.code.ultralog.formatter.def.DefaultThrowableFormatter;
import com.google.code.ultralog.utils.CharacterSequence;

/**
 * An implementation of {@link FormatterFactory} that produces instances of
 * garbage-free formatter classes.
 *
 * @author Mikhail Vladimirov
 */
public class GarbageFreeFormatterFactory implements FormatterFactory
{
    /**
     * Singletom instance of the factory.
     */
    public final static GarbageFreeFormatterFactory INSTANCE =
         new GarbageFreeFormatterFactory ();

    private GarbageFreeFormatterFactory ()
    {
        // Do nothing
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public BooleanFormatter createBooleanFormatter (String options)
    {
        if (options == null)
            throw new IllegalArgumentException ("Options is nul");

        return GarbageFreeBooleanFormatter.INSTANCE;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public ByteFormatter createByteFormatter (String options)
    {
        if (options == null)
            throw new IllegalArgumentException ("Options is nul");

        return GarbageFreeByteFormatter.INSTANCE;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public ShortFormatter createShortFormatter (String options)
    {
        if (options == null)
            throw new IllegalArgumentException ("Options is nul");

        return GarbageFreeShortFormatter.INSTANCE;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public CharacterFormatter createCharacterFormatter (String options)
    {
        if (options == null)
            throw new IllegalArgumentException ("Options is nul");

        return GarbageFreeCharacterFormatter.INSTANCE;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public IntegerFormatter createIntegerFormatter (String options)
    {
        if (options == null)
            throw new IllegalArgumentException ("Options is nul");

        return GarbageFreeIntegerFormatter.INSTANCE;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public LongFormatter createLongFormatter (String options)
    {
        if (options == null)
            throw new IllegalArgumentException ("Options is nul");

        if (options.startsWith ("T"))
            return new GarbageFreeTimestampFormatter (
                options.substring (1), TimeZone.getDefault ());
        else if (options.startsWith ("t"))
            return new GarbageFreeTimestampFormatter (
                options.substring (1), null);
        else return GarbageFreeLongFormatter.INSTANCE;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public FloatFormatter createFloatFormatter (String options)
    {
        if (options == null)
            throw new IllegalArgumentException ("Options is nul");

        return GarbageFreeFloatFormatter.INSTANCE;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public DoubleFormatter createDoubleFormatter (String options)
    {
        if (options == null)
            throw new IllegalArgumentException ("Options is nul");

        return GarbageFreeDoubleFormatter.INSTANCE;
    }

    /**
     * {@inheritDoc}
     */
    @SuppressWarnings("unchecked")
    @Override
    public <T> ReferenceFormatter <? super T> createReferenceFormatter (
        Class <T> type, String options)
    {
        if (type == null)
            throw new IllegalArgumentException ("Type is null");

        if (options == null)
            throw new IllegalArgumentException ("Options is nul");

        if (String.class.equals (type))
            return (ReferenceFormatter <? super T>)
                GarbageFreeStringFormatter.INSTANCE;
        else if (CharacterSequence.class.isAssignableFrom (type))
            return (ReferenceFormatter <? super T>)
                GarbageFreeCharacterSequenceFormatter.INSTANCE;
        else if (CharSequence.class.isAssignableFrom (type))
            return (ReferenceFormatter <? super T>)
                GarbageFreeCharSequenceFormatter.INSTANCE;
        else if (Throwable.class.isAssignableFrom (type))
            return (ReferenceFormatter <? super T>)
                DefaultThrowableFormatter.INSTANCE;
        else return DefaultReferenceFormatter.INSTANCE;
    }
}
